package com.zyao89.view.zloading.ball;

import com.zyao89.view.zloading.ZLoadingBuilder;
import com.zyao89.view.zloading.util.NumCalcUtil;
import ohos.agp.render.Canvas;
import ohos.agp.render.ColorFilter;
import ohos.agp.render.Paint;
import ohos.agp.render.Path;
import ohos.agp.utils.Color;
import ohos.agp.utils.Point;

import java.util.LinkedList;

/**
 * BaseBallBuilder
 *
 * @author jjy
 * @since 2021-03-22
 */
abstract class BaseBallBuilder extends ZLoadingBuilder {
    // 贝塞尔曲线常量
    private static final float PROP_VALUE = 0.551915024494f;

    // 小球点集合
    protected final LinkedList<CirclePoint> mBallPoints = new LinkedList<>();

    // 画笔
    protected Paint mPaint;

    /**
     * 初始化画笔
     *
     * @param lineWidth 画笔线宽
     * @param color 画笔颜色
     */
    protected void initPaint(float lineWidth, Color color) {
        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.FILL_STYLE);
        mPaint.setStrokeWidth(lineWidth);
        mPaint.setColor(color);
        mPaint.setDither(true);
        mPaint.setFilterBitmap(true);
        mPaint.setStrokeCap(Paint.StrokeCap.ROUND_CAP);
        mPaint.setStrokeJoin(Paint.Join.ROUND_JOIN);
    }

    /**
     * initPoints
     *
     * @param ballR 半径
     */
    protected final void initPoints(float ballR) {
        float centerX = getViewCenterX();
        float centerY = getViewCenterY();
        CirclePoint p_0 = new CirclePoint(NumCalcUtil.subtract(centerX, ballR), centerY);
        mBallPoints.add(p_0);
        CirclePoint p_1 = new CirclePoint(NumCalcUtil.subtract(centerX, ballR), NumCalcUtil.add(centerY, ballR * PROP_VALUE));
        mBallPoints.add(p_1);
        CirclePoint p_2 = new CirclePoint(NumCalcUtil.subtract(centerX, ballR * PROP_VALUE), NumCalcUtil.add(centerY, ballR));
        mBallPoints.add(p_2);
        CirclePoint p_3 = new CirclePoint(centerX, NumCalcUtil.add(centerY, ballR));
        mBallPoints.add(p_3);
        CirclePoint p_4 = new CirclePoint(NumCalcUtil.add(centerX, ballR * PROP_VALUE), NumCalcUtil.add(centerY, ballR));
        mBallPoints.add(p_4);
        CirclePoint p_5 = new CirclePoint(NumCalcUtil.add(centerX, ballR), NumCalcUtil.add(centerY, ballR * PROP_VALUE));
        mBallPoints.add(p_5);
        CirclePoint p_6 = new CirclePoint(NumCalcUtil.add(centerX, ballR), centerY);
        mBallPoints.add(p_6);
        CirclePoint p_7 = new CirclePoint(NumCalcUtil.add(centerX, ballR), NumCalcUtil.subtract(centerY, ballR * PROP_VALUE));
        mBallPoints.add(p_7);
        CirclePoint p_8 = new CirclePoint(NumCalcUtil.add(centerX, ballR * PROP_VALUE), NumCalcUtil.subtract(centerY, ballR));
        mBallPoints.add(p_8);
        CirclePoint p_9 = new CirclePoint(centerX, NumCalcUtil.subtract(centerY, ballR));
        mBallPoints.add(p_9);
        CirclePoint p_10 = new CirclePoint(NumCalcUtil.subtract(centerX, ballR * PROP_VALUE), NumCalcUtil.subtract(centerY, ballR));
        mBallPoints.add(p_10);
        CirclePoint p_11 = new CirclePoint(NumCalcUtil.subtract(centerX, ballR), NumCalcUtil.subtract(centerY, ballR * PROP_VALUE));
        mBallPoints.add(p_11);
    }

    protected final void drawBall(Canvas canvas, Path path, Paint paint) {
        path.reset();
        path.moveTo(mBallPoints.get(0).getX(), mBallPoints.get(0).getY());
        path.cubicTo(new Point(mBallPoints.get(1).getX(), mBallPoints.get(1).getY()),
                new Point(mBallPoints.get(2).getX(), mBallPoints.get(2).getY()),
                new Point(mBallPoints.get(3).getX(), mBallPoints.get(3).getY()));
        path.cubicTo(new Point(mBallPoints.get(4).getX(),
                mBallPoints.get(4).getY()), new Point(mBallPoints.get(5).getX(),
                mBallPoints.get(5).getY()), new Point(mBallPoints.get(6).getX(), mBallPoints.get(6).getY()));
        path.cubicTo(new Point(mBallPoints.get(7).getX(),
                mBallPoints.get(7).getY()), new Point(mBallPoints.get(8).getX(),
                mBallPoints.get(8).getY()), new Point(mBallPoints.get(9).getX(), mBallPoints.get(9).getY()));
        path.cubicTo(new Point(mBallPoints.get(10).getX(),
                mBallPoints.get(10).getY()), new Point(mBallPoints.get(11).getX(),
                mBallPoints.get(11).getY()), new Point(mBallPoints.get(0).getX(), mBallPoints.get(0).getY()));
        canvas.drawPath(path, paint);
    }

    @Override
    protected void setAlpha(int alpha) {
        mPaint.setAlpha(alpha);
    }

    @Override
    protected void setColorFilter(ColorFilter colorFilter) {
        mPaint.setColorFilter(colorFilter);
    }

    /**
     * 圆点内部类
     */
    static class CirclePoint {
        private final float mX;
        private final float mY;
        private float mOffsetX = 0;
        private float mOffsetY = 0;
        private boolean mEnabled = true;

        CirclePoint(float x, float y) {
            mX = x;
            mY = y;
        }

        float getX() {
            return NumCalcUtil.add(mX, mOffsetX);
        }

        float getY() {
            return NumCalcUtil.add(mY, mOffsetY);
        }

        void setOffsetX(float offsetX) {
            mOffsetX = offsetX;
        }

        void setOffsetY(float offsetY) {
            mOffsetY = offsetY;
        }

        public void setEnabled(boolean enabled) {
            mEnabled = enabled;
        }

        void draw(Canvas canvas, float r, Paint paint) {
            if (this.mEnabled) {
                canvas.drawCircle(this.getX(), this.getY(), r, paint);
            }
        }
    }
}
